package lt.liepasoft.sudoku;

import java.util.Random;

public class SudokuPuzzleMaker {

	private SudokuSolver solver;
	private Random r;
		
	public SudokuPuzzleMaker() {
		solver = new SudokuSolver();
		r = new Random();
	}
	
	public SudokuTable generateUniqueSudoku(){
		SudokuTable puzzle;
		do {
			puzzle = new SudokuTable();		
			int[] sks={0,3};
			Point p;
			
			int[] possibles;
			for (int fromX: sks){
				for (int fromY: sks){
					p = new Point(fromX+r.nextInt(3), fromY+r.nextInt(3));
					if (puzzle.isCellEmpty(p.x, p.y)){
						possibles = puzzle.possibleInputs(p.x, p.y);
						puzzle.setCell(p.x, p.y, possibles[r.nextInt(possibles.length)]);					
					}
				}	
			}
		} while(!solver.solveSudoku(puzzle));
		return puzzle;
	}
	
	public SudokuTable createPuzzle(){		
		return createPuzzle(generateUniqueSudoku());
	}	
	
	public SudokuTable createPuzzle(SudokuTable sudokuTable){
		SudokuTable puzzle = new SudokuTable();
		
		Grid stencil;
		Point p;
		for (int boxIndex=0; boxIndex<9; boxIndex++){
			stencil = generateStencil();
			p = puzzle.getBoxCoord(boxIndex);
			for (int y=0; y<3; y++) {
				for (int x=0; x<3; x++) {
					if (!stencil.isCellEmpty(x, y)){
						puzzle.setCell(x+p.x, y+p.y, 0);
					} else {
						puzzle.setCell(x+p.x, y+p.y, sudokuTable.getCell(x+p.x, y+p.y));
					}
				}
			}
		}
		
		return puzzle;
	}
	
	private Grid generateStencil(){
		Grid stencil = new Grid(3);
		for (int x=0; x<3; x++) {
			for (int y=0; y<3; y++) {
				if (r.nextBoolean()){
					stencil.setCell(x, y, 1);
				}
			}
		}
		return stencil;
	}
}
